package com.xiaodou.mjf.web.xface.core.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.mysql.fabric.xmlrpc.base.Param;
import com.xiaodou.mjf.application.core.service.OrderService;
import com.xiaodou.mjf.entity.core.Order;
import com.xiaodou.mjf.infrastructure.common.controller.ApplicationController;

import com.xiaodou.mjf.infrastructure.common.utils.StringUtils;
import com.xiaodou.mjf.infrastructure.payeco.tools.http.HttpClient;
import com.xiaodou.mjf.web.xface.common.API;
import com.xiaodou.mjf.web.xface.common.ResultCode;
import com.xiaodou.mjf.web.xface.core.domain.InvokeLogVO;
import com.xiaodou.mjf.web.xface.core.domain.OrderVO;
import com.xiaodou.mjf.web.xface.core.utils.Decrypt;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;
import java.util.Map;

/**
 * Created by 文科 on 2015/3/11.
 */
@Controller
@RequestMapping("v1/core")
public class H5PaymentController extends ApplicationController {

    @Resource
    OrderService orderService;

    @RequestMapping("payment/h5.html")
    public String h5(String param,HttpServletRequest request,Model model){

        try {

            param = Decrypt.doDecrypt(param);


            model.addAttribute("returnUrl",API.getReturnUrl());

            if (param == null) {
                model.addAttribute("message", "订单参数验证失败！");
                model.addAttribute("code", ResultCode.PAYECO_SIGN_ERROR);
                return "pay/h5";
            }

            ObjectMapper objectMapper = new ObjectMapper();

            Map<String,String> map = objectMapper.readValue(param,Map.class);

            if(map.get("channel_id").startsWith("2") && ( !map.containsKey("merchant_id") || StringUtils.isBlank(map.get("merchant_id")))){
                model.addAttribute("message", "商户号不能为空");
                model.addAttribute("code", ResultCode.PAYECO_SIGN_ERROR);
                return "pay/h5";
            }

            String extOrderId = map.get("order_id");

            Order order = orderService.get(extOrderId, Order.HAS_PAID);
            if(order != null){
                model.addAttribute("code","2000");
                model.addAttribute("message","该订单已支付！");

                return "pay/h5";
            }

            String code = request.getParameter("code");
            String message = request.getParameter("message");
            if(StringUtils.isBlank(code)) {
                code = "0000";
            }
            model.addAttribute("code",code);
            model.addAttribute("message",message);
            model.addAttribute("params",map);

        }catch (Exception e){
            e.printStackTrace();
        }

        return "pay/h5";
    }

    @RequestMapping("payment/process.html")
    public void process_(HttpServletRequest request,HttpServletResponse response){

        Map<String,String> params = Maps.newHashMap();

        Enumeration<String> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()){
            String paramName = paramNames.nextElement();
            params.put(paramName,request.getParameter(paramName));
        }

        String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUBpzutmxJlr1sO7XraszmdRIaFJLAq8cOqZbd+ciOBytES1ZSkZwa0jGkSUP1SGynev2T+fTVEyc2IXr/vKEepuwY+6zI/3ir+px2nnc3vwhdhfw5+tKWdrNZr6HHTGYolYq6bKd4E5lb2hV1alkVbpNw7FM5ESZpZa8rChDEywIDAQAB";

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(PUBLIC_KEY));
        try {
            KeyFactory factory = KeyFactory.getInstance("RSA");
            Key publicKey = factory.generatePublic(keySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);

            byte[] data = new ObjectMapper().writeValueAsString(params).getBytes();

            byte[] buffer = null;

            for (int i = 0; i < data.length; i += 64) {
                byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,
                        i + 64));
                buffer = ArrayUtils.addAll(buffer,doFinal);

            }

            String param = Base64.encodeBase64String(buffer);

            String url = API.getHost() + "/v1/core/invoke?param=";
            url += param;

            response.sendRedirect(url);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
